#include <iostream>
#include <stack>
#include <queue>
#include <string>
#include <cstdlib>

// 错误处理函数
void _err_exp();

int main(int argc, char* argv[])
{
	char c;   // 读入缓冲区
	std::stack<char> op;    // 操作符栈
	std::queue<char> exp;   // 后缀表达式队列
	bool point = false;     // 小数点使用标志
        bool flag = false;      //标记前一有效输入是否为数字
	while (true)
	{
		c = std::getchar();
		// 输入以回车结束
		if (c == '\n')
			break;
		// 数字直接输出
		if (c >= '0' && c <= '9')
		  {exp.push(c); flag = true;}
		// 允许小数点
		else if (c == '.')
			// 只允许一个小数点
			if (point == false)
			{
				exp.push(c);
				point = true; flag = false;
			}
			else
				_err_exp();
		// 这一段逻辑和括号匹配类似, 但只考虑小括号
		else if (c == ')')
		{
		  if (op.empty()||op.top() == '('||flag == false)
				_err_exp();
		  //合法情况下右括号前只能是数字，因此要及时做标记
		  exp.push(';'); flag = false;
		  // 一对括号内的全部运算符都应该输出
		  while (!op.empty() && op.top() != '(')
			{
			  exp.push(op.top());
				op.pop();
			}
		        if(!op.empty() && op.top() == '(') {
			  op.pop(); }
			else _err_exp();
		}
		else if (c == '+' || c == '-')
		{
		  //如果前面是数字，则读取结束
		  if (flag == true) exp.push(';');
		  flag = false;
			// 加减运算优先级低, 所以清空全部运算符, 
			// 直到遇到左括号或者空栈.
			if (!op.empty())
			{
				while (!op.empty() && op.top() != '(')
				{
				  exp.push(op.top());
					op.pop();
				}
			}
			// 插入当前的 +/- 运算符
			op.push(c);
			// 准备输入数字
			point = false;
		}
		else if (c == '*' || c == '/')
		{
		  //如果前面是数字，则读取结束
		  if(flag == true)exp.push(';');
		  flag = false;
			if (!op.empty())
			{
				// 只清空同级别运算符
				while (!op.empty() && 
				       (op.top() == '*' || op.top() == '/'))
				{
				  exp.push(op.top());
					op.pop();
			  					}
			}
			op.push(c);
			point = false;
		}
		else if (c == '(')
		  {
		    //合法情况下左括号前不能是数字
		    if(flag == true) _err_exp();
		    flag = false;op.push(c);
		  }
		else
			continue;
	}
	// 输入完毕, 但操作符栈中可能还有运算符,
	// 全部输出到后缀表达式队列中
	// 但在此之前先标记数字的读取结束
	if (flag == true) exp.push(';');
	if (!op.empty())
	{
		while (!op.empty())
		{
		  if(op.top()=='(')
		    _err_exp();
		  exp.push(op.top());
		  op.pop();
		}
	} 
	
	//计算后缀表达式

	std::stack<double> operand;
	std::string num = "";
        while(!exp.empty())
	  {
	    //每次读取一个exp队列里的字符
	      char token = exp.front();
	      exp.pop();
	      //读到数字时先作为字符串存放到num里
	      if (token >= '0' && token <= '9'|| token == '.')
		{
		  num += token ;
		}
	      //读到’；‘时将存放在num里的字符串转化为浮点数存入栈operand
	      else if(token == ';')
		{
		  if(!num.empty())
		    { double number = std::stod(num);// 将字符串转换为浮点数
		      num="";
		      operand.push(number);
		    }
		  else _err_exp();//应该出现数字的地方却没有出现数字，说明表达式不合法
		}
	      else
		{
		  if (operand.size() < 2)  _err_exp(); //该运算的地方没法运算，说明表达式不合法      
		  double operand2 = operand.top();
		  operand.pop();
		  double operand1 = operand.top();
		  operand.pop();
		  double result;
		  if (token == '+')
		    result = operand1 + operand2;
		  else if (token == '-')
		    result = operand1 - operand2;
		  else if (token == '*')
		    result = operand1 * operand2;
		  else if (token == '/')
		    {
		      if (operand2 == 0) _err_exp();//除数不能为0
		      result = operand1 / operand2;
		    }
		  operand.push(result);
		}
	  }
	//exp队列的最后一个元素是数字时，也要将它推入operand栈
	if(!num.empty())
	  { double number = std::stod(num);
	    num="";
	    operand.push(number);
	  }
	if (operand.size() != 1) _err_exp();//最终结果只能唯一
	std::cout << "" << operand.top() << std::endl;	      
	return 0;
};

void _err_exp()
{
	std::cout << "Error." << std::endl;
	exit(-1);
};
